/**
 * 
 */
package com.googlecode.pcapj;

import java.io.ByteArrayInputStream;
import java.io.InputStream;


/**
 * 
 */
class TCPPacketImpl extends PacketImpl implements TCPPacket{
	private byte[] options = null;
	
	/**
	 * @param buffer
	 * @param offset
	 * @param length
	 */
	TCPPacketImpl(byte[] buffer, int offset, int length) {
		super(buffer, offset, length);
		
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getSource()
	 */
	public int getSource() {
		return binaryData.getIntFromWord(0);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getDestination()
	 */
	public int getDestination() {
		return binaryData.getIntFromWord(2);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getSequenceNumber()
	 */
	public long getSequenceNumber() {
		return binaryData.getLongFromDWord(4);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getACK()
	 */
	public long getACK() {
		return binaryData.getLongFromDWord(8);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getDataOffset()
	 */
	public int getDataOffset() {
		return (0xf0 & binaryData.getByte(12)) >> 4;
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#isURG()
	 */
	public boolean isURG() {
		return binaryData.getBit(106);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#isACK()
	 */
	public boolean isACK() {
		return binaryData.getBit(107);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#isPSH()
	 */
	public boolean isPSH() {
		return binaryData.getBit(108);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#isRST()
	 */
	public boolean isRST() {
		return binaryData.getBit(109);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#isSYN()
	 */
	public boolean isSYN() {
		return binaryData.getBit(110);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#isFIN()
	 */
	public boolean isFIN() {
		return binaryData.getBit(111);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getWindow()
	 */
	public int getWindow() {
		return binaryData.getIntFromWord(14);
	}

	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getChecksum()
	 */
	public short getChecksum() {
		return binaryData.getShort(16);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getUrgentPointer()
	 */
	public short getUrgentPointer() {
		return binaryData.getShort(18);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getOptions()
	 */
	public byte[] getOptions() {
		if(options == null){
			int dataOffset = getDataOffset() * 4;
			options = binaryData.getBytes(20, dataOffset - 20);
		}
		return options;
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getData()
	 */
	public byte[] getData() {
		int length = getDataOffset() * 4;
		return binaryData.getBytes(length);
	}
	/* (non-Javadoc)
	 * @see com.googlecode.pcapj.TCPPacket#getDataInputStream()
	 */
	public InputStream getDataInputStream() {
		int offset = getDataOffset() * 4;
		int length = binaryData.getLength() - offset;
		return new ByteArrayInputStream(binaryData.getBuffer(), offset, length);
	}
}
